# -*- coding: utf-8 -*-
"""
Module Description: 活动相关常规通用方法
Date: 2018/3/31
Author: FQ
"""
from pyshare.dal.repository_impl import CrossRuinsActivityRepository, CrossCateActivityRepository, \
    CrossRankActivityRepository, CrossSiegeActivityRepository, CrossChessActivityRepository, \
    CrossSoccerActivityRepository, CrossRehearseActivityRepository, CrossNaadamActivityRepository, \
    CrossContendActivityRepository, CrossSaintAscendActivityRepository, CrossFestivalShopActivityRepository, \
    CrossQueenActivityRepository, CrossLotteryActivityRepository, CrossBanquetActivityRepository, \
    CrossIslandActivityRepository, CrossClearanceActivityRepository, CrossMonopolyActivityRepository, \
    CrossSiegelordFieldRepository, CrossCeladonActivityRepository, CrossActivityExtraAwardRepository, \
    CrossTowerActivityRepository, CrossFishActivityRepository
from pyshare.dal.repository_impl.cross_group_purchase_repository import CrossGroupPurchaseActivityRepository
from pyshare.dal.repository_impl.live_activity_repository import LiveActivityRepository
from pyshare.utils.list_utils import list_to_dict
from pyshare.utils.time_utils import strToDatetime, get_another_time, checkStrIsDatetime, getCT, replace_clock_time
from pyshare.utils.json_utils import dumps
from pyshare.const.lang.tips_info import TipsInfo
from pyshare.const.enums.activity import ActivityExtraStatusList
from pyshare.dal.dal_adapters import cross_adapters as cross_adt
from pyshare.framework.error_handle import CrossAdminGameException

import datetime


def end_time_to_string(end_time):
    """活动结束时间特殊处理00:00:00 改成前一天23:59:59"""
    if not isinstance(end_time, str):
        end_time = str(end_time)
    _, time = end_time.split(' ', 1)
    end_time_date = strToDatetime(end_time)
    if time == '00:00:00' or time == '0:0:0':
        return get_another_time(end_time_date, seconds=-1)
    return end_time_date


def change_end_time_by_open_time(end_time, open_time):
    """
    比较每日开启时间，修改结束时间
    :param end_time: datetime
    :param open_time: ["10:00:00", "22:00:00"]
    :return:
    """
    open_end_time = replace_clock_time(end_time, open_time[1])
    return open_end_time if end_time > open_end_time else end_time


def check_time_param(*times):
    """
    检测时间参数列表，
    :param times: 时间列表，按时间先后顺序
    :return:
    """
    error_info = TipsInfo.CrossActivity.ActivityConfigTimeError
    # 检测参数是否符合时间格式
    for index, time_param in enumerate(times):
        if not (checkStrIsDatetime(time_param)):
            return False, error_info

        if index > 0:
            if strToDatetime(times[index - 1]) >= strToDatetime(time_param):
                return False, error_info
    return True, ''


def check_activity_time_param(start_time, end_time, show_time=None, award_end_time=None, is_check_now=True):
    """
    活动时间常规检查
    :param start_time: 活动开始时间
    :param end_time: 活动结束时间
    :param show_time: 活动展示/报名开始时间
    :param award_end_time: 领奖结束时间
    :param is_check_now: 默认True表示end_time必须大于当前时间
    :return:
    """
    error_info = TipsInfo.CrossActivity.ActivityConfigTimeError
    if not (checkStrIsDatetime(start_time) and checkStrIsDatetime(end_time)):
        raise CrossAdminGameException(error_info)
    start_time = strToDatetime(start_time)
    end_time = strToDatetime(end_time)
    if start_time >= end_time:
        raise CrossAdminGameException(error_info)
    if is_check_now and end_time < getCT():
        raise CrossAdminGameException(error_info)
    if show_time:
        if not checkStrIsDatetime(show_time) or strToDatetime(show_time) > start_time:
            raise CrossAdminGameException(error_info)

    if award_end_time:
        if not checkStrIsDatetime(award_end_time) or strToDatetime(award_end_time) <= end_time:
            raise CrossAdminGameException(error_info)
    return True, ''


def check_award_format(award_list):
    """
    检测奖励格式是否是三层
    :param award_list:
    :return:
    """
    error_info = TipsInfo.CrossActivity.AwardFormatError
    if not isinstance(award_list, list):
        raise CrossAdminGameException(error_info)

    # 直接检测字段长度是否超过上限，每档奖励个数不做限制
    for index, awards in enumerate(award_list):
        for a in awards:
            if not isinstance(a, list) or len(a) != 3:
                raise CrossAdminGameException(error_info)
    return True, ''


def check_rank_range(rank_range_list, actor=0):
    """
    检测排名区间
    :param rank_range_list:
    :param actor: 资格人数检测
    :return:
    """
    error_info = TipsInfo.CrossActivity.RangeConfigError
    act_flag = False
    for index, rank_range in enumerate(rank_range_list):
        if len(rank_range) != 2:
            # 长度2位
            raise CrossAdminGameException(error_info)
        if index == 0 and rank_range[0] != 1:
            # 排名要从第一名开始
            raise CrossAdminGameException(error_info)
        if rank_range[0] > rank_range[1]:
            raise CrossAdminGameException(error_info)
        if index + 2 <= len(rank_range_list) and rank_range_list[index][1] + 1 != rank_range_list[index + 1][0]:
            # 判断上一个区间和下一个区间是否连续
            raise CrossAdminGameException(error_info)
        if 0 < actor == rank_range[1]:
            act_flag = True
    if actor > 0 and not act_flag:
        raise CrossAdminGameException(error_info)

    return True, ''


def check_config_data(config_data):
    """
    检测config_data 必须按顺序
    :param config_data:
    :return:
    """
    new_data = sorted(config_data, key=lambda x: x[0], reverse=False)
    if new_data != config_data:
        return False
    return True


def check_max_length(adapter, **activity_dict):
    """
    字段长度检测
    对活动配置中如档位相关的字段做长度检测
    需检测字段由枚举文件中配置
    :param activity_dict: 需检测的活动数据字段字典
    :param adapter: 适配器
    :return:
    """

    from pyshare.dal.dal_adapters import USE_DATA_LAYER, DATA_LAYER_CHAOS

    def field_length_chaos(m, field_name):
        f = m.__dict__.get(field_name, None)
        if not f:
            return 0
        return getattr(f, 'max_length', 0)

    def field_length_peewee(m, field_name):
        if not getattr(m, field_name, None):
            return 0
        return getattr(getattr(m, field_name), 'max_length')

    model = adapter.model_class
    if USE_DATA_LAYER == DATA_LAYER_CHAOS:
        func = field_length_chaos
    else:
        func = field_length_peewee
    for field, data in activity_dict.iteritems():
        len1 = len(dumps(data))
        len2 = func(model, field)
        if len(dumps(data)) > func(model, field):
            return False, field
    return True, ''


def is_change_value(new_value, old_value):
    if new_value is not None:
        if new_value == old_value:
            return new_value, False
        return new_value, True

    return old_value, False


def get_award_index(rank, range_cfg):
    """
    获取排名奖励下标
    :param rank: 排名
    :param range_cfg: 排名奖励区间
    :return:
    """
    award_index = -1
    for index, r in enumerate(range_cfg):
        if r[0] <= rank <= r[1]:
            return index
    return award_index


class BaseActivityCheck(object):
    """
    后台活动参数检测类
    """
    activity_adapter = None
    activity_id_field = 'activity_id'

    @staticmethod
    def activity_start_time(activity):
        return activity.start_time

    @staticmethod
    def server_list(activity):
        return activity.server_list

    @staticmethod
    def get_going_activity(**kwargs):
        """
        获取进行中的活动用于检测时间重复
        :return:
        """
        raise Exception('function get_going_activity of BaseActivityCheck not rewrite')

    @staticmethod
    def if_award_match_range(award, range_list):
        """
        检测奖励和区间格式以及是否匹配
        :param award:
        :param range_list:
        :return:
        """
        # 检测AwardList 和 Range
        if len(award) != len(range_list):
            raise CrossAdminGameException(TipsInfo.CrossActivity.AwardNotMatchRange)

        # 校验奖励格式
        check_award_format(award)

        # 校验排名区间
        check_rank_range(range_list)

        return True

    @classmethod
    def check_activity_award_rang(cls, award, range_list, model_field):
        """
        检测活动奖励和排名区间
        :param award: 待检测的奖励列表
        :param range_list: 待检测的排名区间列表
        :param model_field: model中对应的字段，用于表结构字段长度检测 eg: ['AwardList', 'RangeList']
        :return:
        """
        # 表结构字段长度检测
        f, i = check_max_length(cls.activity_adapter, **{model_field[0]: award, model_field[1]: range_list})
        if not f:
            raise CrossAdminGameException('字段%s超出最大长度' % i)

        # 校验排名区间和排名奖励
        cls.if_award_match_range(award, range_list)

        return True, ''

    @classmethod
    def is_create_or_update_add_extra_award(cls, activity_id, activity_type, extra_award, extra_range, range_list):
        """
        是否需要创建额外奖励内容
        :param activity_id: 待检测的活动ID
        :param activity_type: 活动类型
        :param extra_award: 待检测的额外奖励列表
        :param extra_range: 待检测的额外排名区间列表
        :param range_list: 待检测的活动排名区间列表
        :return:
        """
        if not activity_id:
            raise CrossAdminGameException('活动id无效' + activity_id)
        if not extra_award or not extra_range:
            return False
        if not isinstance(extra_award, list):
            raise CrossAdminGameException('额外奖励格式错误')

        for index, awards in enumerate(extra_award):
            if not isinstance(awards, list):
                raise CrossAdminGameException('额外奖励格式错误')
            for award in awards:
                if len(award) != 3:
                    raise CrossAdminGameException('额外奖励格式错误')
            if not isinstance(extra_range[index], int):
                raise CrossAdminGameException('额外奖励分数错误')
        if len(extra_award) != len(extra_range):
            raise CrossAdminGameException('额外奖励与积分配置不匹配')
        if cls.if_award_match_range(extra_award, range_list):
            # 创建或者更新额外奖励列表
            extra_activity = CrossActivityExtraAwardRepository.get_by_activity_id(activity_id)
            if not extra_activity:
                CrossActivityExtraAwardRepository.create(activity_id=activity_id,
                                                         activity_type=activity_type,
                                                         extra_award_list=extra_award,
                                                         extra_score_list=extra_range)
            else:
                extra_activity.extra_award_list = extra_award
                extra_activity.extra_score_list = extra_range
                CrossActivityExtraAwardRepository.save(extra_activity)

    @classmethod
    def get_rank_extra_award(cls, activity_id, award_index, score, extra_activity=None):
        """
        获取额外奖励内容
        :param activity_id: 活动ID
        :param award_index: 排名
        :param score: 分数
        :param extra_activity:
        :return:
        """
        reward = []
        if not extra_activity:
            extra_activity = CrossActivityExtraAwardRepository.get_by_activity_id(activity_id)
        if extra_activity:
            # 防止奖励修改导致的领取错误
            # if len(extra_activity.extra_score_list) < award_index - 1 or \
            #      len(extra_activity.extra_score_list) < award_index - 1:
            #  return []
            if score >= extra_activity.extra_score_list[award_index]:
                reward = extra_activity.extra_award_list[award_index]
        return reward

    @classmethod
    def delete_extra_award(cls, activity_id):
        """
        是否需要删除额外奖励内容
        :param activity_id: 活动ID
        :return:
        """
        extra_activity = CrossActivityExtraAwardRepository.get_by_activity_id(activity_id)
        if extra_activity:
            CrossActivityExtraAwardRepository.delete(extra_activity)

    @classmethod
    def get_activity_data_with_extra_award(cls, activity_list, activity_type):
        """
        拼接活动
        :param activity_list: 活动数据
        :param activity_type: 活动类型
        :return:
        """
        extra_list = CrossActivityExtraAwardRepository.filter_by_activity_type(activity_type)
        extra_list_id_dict = list_to_dict(extra_list, 'activity_id')
        return_list = []
        for a in activity_list:
            data = a.asdict()
            activity_id = data['ActivityId']
            if activity_id in extra_list_id_dict.keys():
                data['ExtraAwardList'] = extra_list_id_dict[activity_id].extra_award_list
                data['ExtraScoreList'] = extra_list_id_dict[activity_id].extra_score_list
            return_list.append(data)
        return return_list

    @classmethod
    def activity_check_legal(cls, activity_id, status, server_list, **kwargs):
        """
        检查同类型活动开启状态是否有区服重复
        :param activity_id: 活动id
        :param status: 活动状态
        :param kwargs: 活动预热开始时间
        :param server_list: 参与的区服
        :return:
        """
        if status in ActivityExtraStatusList:
            return True, ""

        for a in cls.get_going_activity(**kwargs):
            a_id = getattr(a, cls.activity_id_field)
            if a_id == activity_id:
                continue

            repeat_set = set(server_list) & set(a.server_list)
            if repeat_set:
                raise CrossAdminGameException('区服列表存在重复，重复活动：%s' % a_id + '重复区服：' + str(repeat_set)[5:-2])
        return True, ''

    @classmethod
    def activity_check_legal_by_allies(cls, activity_id, status, allies_no_list, **kwargs):
        """
        检查同类型活动开启状态是否有同盟国战区重复
        :param activity_id: 活动id
        :param status: 活动状态
        :param kwargs: 活动预热开始时间
        :param allies_no_list: 参与的同盟国战区短编号
        :return:
        """
        if status in ActivityExtraStatusList:
            return True, ""

        for a in cls.get_going_activity(**kwargs):
            a_id = getattr(a, cls.activity_id_field)
            if a_id == activity_id:
                continue

            repeat_set = set(allies_no_list) & set(a.allies_no_list)
            if repeat_set:
                raise CrossAdminGameException('战区列表存在重复，重复活动：%s' % a_id + '重复战区：' + str(repeat_set)[5:-2])
        return True, ''

    @staticmethod
    def model_field_to_adapter_field(model_field):
        """将驼峰转成小写下划线"""
        return ''.join(
            [c.lower() if not c.isalpha() or c.islower() or (c.isupper() and idx == 0)
             else '_%c' % c.lower()
             for idx, c in enumerate(model_field)])

    @staticmethod
    def model_field_to_adapter_field_no_underline(model_field):
        """将驼峰转成小写,无下划线"""
        return ''.join(
            [c.lower() if not c.isalpha() or c.islower() or (c.isupper() and idx == 0)
             else '%c' % c.lower()
             for idx, c in enumerate(model_field)])

    @staticmethod
    def return_default_params(activity, activity_dict):
        """
        返回默认参数
        :param activity:
        :param activity_dict:
        :return:
        """
        new_dict = activity.asdict()
        for key, value in new_dict.iteritems():
            new_value = activity_dict.get(key, None)
            if new_value is None:
                continue
            if isinstance(value, datetime.datetime):
                new_dict[key] = strToDatetime(new_value)
            else:
                new_dict[key] = new_value
        return new_dict

    @classmethod
    def set_attr(cls, activity, activity_dict):
        """设置属性"""
        for key, value in activity_dict.iteritems():
            field = cls.model_field_to_adapter_field(key)
            setattr(activity, field, value)

    @classmethod
    def check_server_list(cls, activity, new_server_list):
        if cls.activity_start_time(activity) < getCT() and (set(new_server_list) - set(cls.server_list(activity))):
            raise CrossAdminGameException('活动已开始，不能修改参与的区服')


class CrossRankCheck(BaseActivityCheck):
    """
    跨服冲榜活动检测类
    """
    activity_adapter = cross_adt.CrossRankActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """

        :param kwargs:
        :return:
        """
        activity_type = kwargs['activity_type']
        award_end_time = kwargs['award_end_time']
        show_time = kwargs['show_time']
        return CrossRankActivityRepository.filter_opening_by_time_interval(activity_type=activity_type,
                                                                           show_time=show_time,
                                                                           award_end_time=award_end_time)


class CrossSiegeCheck(BaseActivityCheck):
    """
    跨服攻城战活动检测类
    """
    activity_adapter = cross_adt.CrossSiegeActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """

        :param kwargs:
        :return:
        """
        award_end_time = kwargs['award_end_time']
        start_time = kwargs['start_time']
        return CrossSiegeActivityRepository.filter_opening_by_time_interval(start_time=start_time,
                                                                            award_end_time=award_end_time)


class CrossRuinsCheck(BaseActivityCheck):
    """
    跨服遗迹活动检测类
    """

    activity_adapter = cross_adt.CrossRuinsActivityAdapter
    activity_id_field = 'ruins_id'

    @staticmethod
    def get_going_activity(**kwargs):
        """

        :param kwargs:
        :return:
        """
        award_end_time = kwargs['award_end_time']
        prepare_start_time = kwargs['prepare_start_time']
        return CrossRuinsActivityRepository.filter_by_prepare_award_time(prepare_start_time, award_end_time)

    @staticmethod
    def return_default_params(activity, activity_dict):
        """
        返回默认参数
        修改活动时，没有上传的参数，使用activity的数据
        activity_dict = {'PrepareStartTime': self.PrepareStartTime, 'StartTime': self.StartTime,
                         'EndTime': self.EndTime, 'AwardEndTime': self.AwardEndTime,
                         'PersonalAwardList': self.PersonalAwardList, 'PersonalRangeList': self.PersonalRangeList,
                         'ActivityStatus': self.ActivityStatus, 'ActivityName': self.ActivityName,
                         'DescStr': self.DescStr, 'AllianceMemberAwardList': self.AllianceMemberAwardList,
                         'AllianceRangeList': self.AllianceRangeList, 'RuinsNum': self.RuinsNum,
                         'ServerList': self.ServerList, 'AllianceLeaderAwardList': self.AllianceLeaderAwardList}
        :param activity: 活动对象
        :param activity_dict: 活动修改参数
        :return:
        """
        return {'PrepareStartTime': strToDatetime(activity_dict.get('PrepareStartTime', activity.prepare_start_time)),
                'StartTime': strToDatetime(activity_dict.get('StartTime', activity.start_time)),
                'EndTime': strToDatetime(activity_dict.get('EndTime', activity.end_time)),
                'AwardEndTime': strToDatetime(activity_dict.get('AwardEndTime', activity.award_end_time)),
                'PersonalAwardList': activity_dict.get('PersonalAwardList', activity.personal_award_list),
                'PersonalRangeList': activity_dict.get('PersonalRangeList', activity.personal_range_list),
                'AllianceMemberAwardList': activity_dict.get('AllianceMemberAwardList',
                                                             activity.alliance_member_award_list),
                'AllianceRangeList': activity_dict.get('AllianceRangeList', activity.alliance_range_list),
                'ActivityStatus': activity_dict.get('ActivityStatus', activity.activity_status),
                'RuinsName': activity_dict.get('RuinsName', activity.ruins_name),
                'DescStr': activity_dict.get('DescStr', activity.desc_str),
                'RuinsNum': activity_dict.get('RuinsNum', activity.ruins_num),
                'ServerList': activity_dict.get('ServerList', activity.server_list),
                'AllianceLeaderAwardList': activity_dict.get('AllianceLeaderAwardList',
                                                             activity.alliance_leader_award_list)}


class CrossCateCheck(BaseActivityCheck):
    """
    跨服美食活动检测类
    """
    activity_adapter = cross_adt.CrossCateActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """

        :param kwargs:
        :return:
        """
        activity_type = kwargs['activity_type']
        award_end_time = kwargs['award_end_time']
        start_time = kwargs['start_time']
        return CrossCateActivityRepository.filter_by_type_time(activity_type, start_time, award_end_time)


class CrossChessCheck(BaseActivityCheck):
    """
    跨服棋局活动检测类
    """
    activity_adapter = cross_adt.CrossChessActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """

        :param kwargs:
        :return:
        """
        award_end_time = kwargs['award_end_time']
        start_time = kwargs['start_time']
        return CrossChessActivityRepository.filter_by_time(start_time, award_end_time)


class CrossSoccerCheck(BaseActivityCheck):
    """
    跨服足球活动检测类
    """
    activity_adapter = cross_adt.CrossSoccerActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossSoccerActivityRepository.filter_by_time(start_time, award_end_time)


class CrossRehearseCheck(BaseActivityCheck):
    """
    跨服健锐活动检测类
    """
    activity_adapter = cross_adt.CrossRehearseActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossRehearseActivityRepository.filter_by_time(start_time, award_end_time)


class CrossNaadamCheck(BaseActivityCheck):
    """
    跨服那达慕活动检测类
    """
    activity_adapter = cross_adt.CrossNaadamActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossNaadamActivityRepository.filter_by_time(start_time, award_end_time)


class CrossContendCheck(BaseActivityCheck):
    """
    跨服百家争鸣活动检测类
    """
    activity_adapter = cross_adt.CrossContendActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossContendActivityRepository.filter_by_time(start_time, award_end_time)


class CrossSaintCheck(BaseActivityCheck):
    """
    跨服圣君登基活动检测类
    """
    activity_adapter = cross_adt.CrossSaintAscendActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        end_time = kwargs['end_time']
        activity_type = kwargs['activity_type']
        return CrossSaintAscendActivityRepository.filter_by_time(start_time, end_time, activity_type)


class CrossFestivalShopCheck(BaseActivityCheck):
    """
    跨服节日商城活动检测类
    """
    activity_adapter = cross_adt.CrossFestivalShopActivityAdapter

    @classmethod
    def activity_check_not_end(cls, activity_id, status, server_list, **kwargs):
        """
        检查正在开放或将要开放的同类型活动是否有区服重复
        :param activity_id: 活动id
        :param status: 活动状态
        :param kwargs: 活动预热开始时间
        :param server_list: 参与的区服
        :return:
        """
        if status in ActivityExtraStatusList:
            return True, ""

        for a in cls.get_not_end_activity(**kwargs):
            a_id = getattr(a, cls.activity_id_field)
            if a_id == activity_id:
                continue

            repeat_set = set(server_list) & set(a.server_list)
            if repeat_set:
                raise CrossAdminGameException('{}区服等待最近活动结束后，才能配置新活动。'.format(str(repeat_set)[5:-2]))

        return True, ''

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        end_time = kwargs['end_time']
        return CrossFestivalShopActivityRepository.filter_by_time(start_time, end_time)

    @staticmethod
    def get_not_end_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        end_time = kwargs['end_time']
        return CrossFestivalShopActivityRepository.filter_by_end_time(end_time)


class CrossLotteryCheck(BaseActivityCheck):
    """
    跨服抽奖活动检测类
    """
    activity_adapter = cross_adt.CrossLotteryActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossLotteryActivityRepository.filter_by_time(start_time, award_end_time)


class CrossQueenCheck(BaseActivityCheck):
    """
    跨服如意赠佳人活动检测类
    """
    activity_adapter = cross_adt.CrossQueenActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossQueenActivityRepository.filter_by_time(start_time, award_end_time)


class CrossBanquetCheck(BaseActivityCheck):
    """
    跨服满汉全席活动检测类
    """
    activity_adapter = cross_adt.CrossBanquetActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossBanquetActivityRepository.filter_by_time(start_time, award_end_time)


class CrossIslandCheck(BaseActivityCheck):
    """
    跨服蓬莱仙岛活动检测
    """
    activity_adapter = cross_adt.CrossIslandActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossIslandActivityRepository.filter_by_time(start_time, award_end_time)


class CrossGroupPurchaseCheck(BaseActivityCheck):
    """
    跨服团购礼包活动检测
    """
    activity_adapter = cross_adt.CrossGroupPurchaseActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossGroupPurchaseActivityRepository.filter_by_time(start_time, award_end_time)


class LiveActivityCheck(BaseActivityCheck):
    """
    直播活动检测类
    """
    activity_adapter = cross_adt.LiveActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        end_time = kwargs['end_time']
        return LiveActivityRepository.filter_by_time(start_time, end_time)

    @staticmethod
    def get_not_end_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        end_time = kwargs['end_time']
        return LiveActivityRepository.filter_by_end_time(end_time)


class CrossClearanceCheck(BaseActivityCheck):
    """
    跨服三消活动检测类
    """
    activity_adapter = cross_adt.CrossClearanceActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossClearanceActivityRepository.filter_by_time(start_time, award_end_time)


class CrossMonopolyCheck(BaseActivityCheck):
    """
    跨服大富翁活动检测类
    """
    activity_adapter = cross_adt.CrossMonopolyActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossMonopolyActivityRepository.filter_by_time(start_time, award_end_time)


class CrossSiegelordCheck(BaseActivityCheck):
    """
    跨服攻城掠地活动检测
    """
    activity_adapter = cross_adt.CrossSiegelordFieldAdapter

    activity_id_field = 'field_id'

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossSiegelordFieldRepository.filter_by_time(start_time, award_end_time)

    @classmethod
    def activity_check_legal_by_allies(cls, activity_id, status, allies_no_list, **kwargs):
        """
        检查同类型活动开启状态是否有同盟国战区重复
        :param activity_id: 活动id
        :param status: 活动状态
        :param kwargs: 活动预热开始时间
        :param allies_no_list: 参与的同盟国战区短编号
        :return:
        """
        if status in ActivityExtraStatusList:
            return True, ""

        for a in cls.get_going_activity(**kwargs):
            a_id = getattr(a, cls.activity_id_field)
            if a_id == activity_id:
                continue

            repeat_set = set(allies_no_list) & set(a.allies_no_list)
            if repeat_set:
                raise CrossAdminGameException('战区列表存在重复，重复活动：%s' % a_id + '重复战区：' + str(repeat_set)[5:-2])
        return True, ''


class CrossCeladonCheck(BaseActivityCheck):
    """
    跨服青瓷御器活动检测类
    """
    activity_adapter = cross_adt.CrossCeladonActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossCeladonActivityRepository.filter_by_time(start_time, award_end_time)


class CrossTowerCheck(BaseActivityCheck):
    """
    跨服爬塔活动检测类
    """
    activity_adapter = cross_adt.CrossTowerActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossTowerActivityRepository.filter_by_time(start_time, award_end_time)


class CrossFishCheck(BaseActivityCheck):
    """
    跨服钓鱼活动检测类
    """
    activity_adapter = cross_adt.CrossFishActivityAdapter

    @staticmethod
    def get_going_activity(**kwargs):
        """
        :param kwargs:
        :return:
        """
        start_time = kwargs['start_time']
        award_end_time = kwargs['award_end_time']
        return CrossFishActivityRepository.filter_by_time(start_time, award_end_time)
